import { ElMessage } from 'element-plus'
import router from './router'
import { useUserStore } from './stores/user'
import { getProfileAPI } from './apis/user'
import type { RouteRecordRaw } from 'vue-router'
import { asyncRoutes } from './router/asyncRoutes'
import { useMenuStore } from './stores/menu'

/**
 * 处理一级路由数据
 */
const getFirstRoutePerms = (permissions: string[]) => {
  const firstRoute = permissions.map(item => item.split(':')[0])
  return [...new Set(firstRoute)]
}

/**
 * 处理二级路由数据
 */
const getSecondRoutePerms = (permissions: string[]) => {
  const secondRoute = permissions.map(item => {
    const res = item.split(':')
    return res[0] + ':' + res[1]
  })
  return [...new Set(secondRoute)]
}

/**
 * 根据权限标识过滤路由表
 */
const getRoutes = (
  firstRoutePerms: string[],
  secondRoutePerms: string[],
  asyncRoutes: RouteRecordRaw[]
) => {
  // 如果是超级管理员，则直接返回路由表 '*:*:*'
  if (firstRoutePerms.includes('*')) {
    return asyncRoutes
  }
  // 根据权限筛选出一级路由
  const firstRoute = asyncRoutes.filter(route => {
    return firstRoutePerms.includes(route.meta!.permission!)
  })
  // 在一级路由基础上再次筛选出最终路由
  const lastRoute = firstRoute.map(route => {
    return {
      ...route,
      children: route.children?.filter(child => {
        return secondRoutePerms.includes(child.meta!.permission!)
      })
    }
  })
  return lastRoute
}

// 定义白名单路由，这些路由不需要登录就可以访问
const WHITE_LIST = ['/login', '/404']

// 全局路由守卫，用于在路由跳转前进行登录状态检查
router.beforeEach(async (to, from, next) => {
  // 非vue组件获取store,在使用前获取,避免pinia还没创建完成
  const store = useUserStore()
  // 如果用户已登录，则直接放行
  if (store.token) {
    if (!store.profile.id) {
      // store.setProfile((await getProfileAPI()).data)
      const res = await getProfileAPI()
      store.setProfile(res.data)
      // 1. 处理一级路由数据
      const menus = getFirstRoutePerms(res.data.permissions)
      // 2. 处理二级路由数据
      const smenus = getSecondRoutePerms(res.data.permissions)
      // 3. 根据权限标识过滤路由表
      const perRoute = getRoutes(menus, smenus, asyncRoutes)
      console.log('最终路由', perRoute)
      // 4. 添加到路由表中
      perRoute.forEach(item => {
        router.addRoute(item as RouteRecordRaw)
      })
      // 5. 保存到pinia
      const menuStore = useMenuStore()
      menuStore.setMenuList(perRoute as RouteRecordRaw[])

      next({ ...to })
    } else {
      // 如果用户有权限，则直接放行
      next()
    }
  } else {
    // 如果用户未登录，检查目标路由是否在白名单内
    if (WHITE_LIST.includes(to.path)) {
      next()
    } else {
      // 如果目标路由不在白名单内，则重定向到登录页面
      next('/login')
      // 提示用户需要先登录
      ElMessage.warning('未获取到登录信息,请先登录')
    }
  }
})
